<template>
  <Form
    ref="formRef"
    :model="categoryForm"
    :rules="rules"
    :labelCol="{ span: 2 }"
    :wrapperCol="{ span: 22 }"
  >
    <FormItem name="category">
      <Spin :spinning="loading.state.value">
        <div v-if="!categories.length">
          <TypographyText type="secondary">无分类</TypographyText>
        </div>
        <Tree
          v-else
          class="category-select"
          :show-line="true"
          :checkable="true"
          :block-node="true"
          :default-expand-all="true"
          :check-strictly="true"
          :tree-data="
            getAntdTreeByTree({
              tree: categories,
              valuer: (c) => c._id,
            })
          "
          v-model:checkedKeys="categoryForm.category"
          @check="handleCheck"
        >
          <template #title="{ dataRef }">
            <Space size="small">
              <TypographyText :strong="true">
                {{ dataRef.data?.name }}
              </TypographyText>
              <Divider type="vertical" />
              {{ dataRef.data?.slug }}
            </Space>
          </template>
        </Tree>
      </Spin>

      <Divider />
      <Button size="small" type="dashed" :loading="loading.state.value" @click="fetchCategories">
        <template #icon>
          <ReloadOutlined />
        </template>
        刷新列表
      </Button>
    </FormItem>
  </Form>
</template>

<script setup lang="ts">
import { onMounted, PropType, reactive, ref, toRaw, watchEffect } from 'vue'
import {
  Button,
  Divider,
  Form,
  FormInstance,
  FormItem,
  Space,
  Spin,
  Tree,
  TypographyText,
} from 'ant-design-vue'
import { ReloadOutlined } from '@ant-design/icons-vue'
import { useLoading } from '@/handcer'
import type { Article } from '@/constants/article'

import { CategoryTree, getAntdTreeByTree, getCategories } from '@/store/category'

export type CategoryFormModel = Pick<Article, 'category'>

export interface CategoryFormExpose {
  validate: () => Promise<CategoryFormModel>
}

const props = defineProps({
  form: {
    type: Object as PropType<CategoryFormModel>,
  },
})

// 获取标签
const formRef = ref<FormInstance>()
const categoryForm = reactive<CategoryFormModel>({
  category: [],
})

const rules = {
  category: [
    {
      required: true,
      message: '至少应该选择一个分类',
    },
  ],
}

// 分类
const loading = useLoading()
const categories = ref<Array<CategoryTree>>([])
const fetchCategories = () => {
  loading.promise(getCategories({ per_page: 50 })).then((result) => {
    categories.value = result.tree
  })
}

// 选中节点
const handleCheck = (
  checked:
    | Array<number | string>
    | { checked: Array<number | string>; halfChecked: Array<number | string> }
) => {
  if (Array.isArray(checked)) {
    categoryForm.category = checked
  } else {
    categoryForm.category = checked.checked
  }
}

const validate = () => {
  return new Promise<CategoryFormModel>((resolve, reject) => {
    formRef.value
      ?.validateFields()
      .then(() => {
        const data = toRaw(categoryForm)
        resolve(data)
      })
      .catch((err) => {
        formRef.value?.scrollToField('category', {
          behavior: 'smooth',
        })
        reject(err)
      })
  })
}

watchEffect(() => {
  categoryForm.category = props.form?.category!
})

onMounted(() => {
  fetchCategories()
})

// 暴露方法
defineExpose({
  validate,
})
</script>

<style lang="less" scoped></style>
